/******************************************************************************
 * $Id: focusbar.c,v 1.16 2004/09/22 01:14:22 jimb Exp $
 * @file
 * @author	Jim Brooks http://www.jimbrooks.org
 * @brief	"focus bar" widget functions.
 * @remarks @verbatim
 * Only focusbar code belongs here.
 *
 * How to use the focusbar bar widget:
 *
 * 1. Create focusbar using FocusbarCreate().
 * 2. Register callbacks for the events "focus-in[out]-event",
 *    which call FocusbarFocusGain[Lost], resp.
 * 3. Register a callback for the expose event, which should call FocusbarPaint().
 * 4. Don't use internal funcs ;-)
 *
 * Notes : Originally, the background colors of the text and notebook widgets
 *         were changed to indicate focus.  However, during a resize,
 *         the color of the text widget would spill into the notebook widget
 *         (both being inside a pane widget).  So that is why this
 *         focusbar widget was written.
 * @endverbatim
 ******************************************************************************/

#include "common.h"
#include "focusbar.h"

#include "widgets.h"

#define FOCUSBAR_WIDTH_DEFAULT          200
#define FOCUSBAR_TEXT_OFFSET_FROM_LEFT	80
#define FOCUSBAR_TEXT_PADDING_TOP		0
#define FOCUSBAR_TEXT_PADDING_BOTTOM	4

/*
 * Internal function prototypes.
 */
static void FocusbarPaintFocusGain( focusbar_t* pFocusbar );
static void FocusbarPaintFocusLose( focusbar_t* pFocusbar );
static void FocusbarLabelDraw( focusbar_t* pFocusbar );

/*****************************************************************************
 * Create a focus bar.
 *
 * @param	pFontName
 *          Name of desired font, or pass NULL to use default font.
 *****************************************************************************/
focusbar_t*
FocusbarCreate( char* pFontName )
{
   focusbar_t* pFocusbar = g_malloc( sizeof(focusbar_t) );
   GtkStyle*	pStyle   = NULL;
   GdkColor     color    = { 0, COLOR_FOCUS_BG_RED, COLOR_FOCUS_BG_GREEN, COLOR_FOCUS_BG_BLUE };

  /*
   * Create a drawing widget.
   * If specified, change the font.
   * Heighten drawing widget to accommodate font.
   */
   pFocusbar->pWidget = gtk_drawing_area_new();

   if ( pFontName  &&  pFontName[0] ) ChangeStyleFont( pFocusbar->pWidget, pFontName );

   pStyle = gtk_widget_get_style( pFocusbar->pWidget );

   pFocusbar->fontHeight = FontHeight( pStyle->font_desc ) + FOCUSBAR_TEXT_PADDING_TOP + FOCUSBAR_TEXT_PADDING_BOTTOM; //lv

   gtk_drawing_area_size( GTK_DRAWING_AREA(pFocusbar->pWidget),
                          FOCUSBAR_WIDTH_DEFAULT,	/* width */
                          pFocusbar->fontHeight );	/* height */

  /*
   * Fill the rest of the struct focusbar_t.
   */
   pFocusbar->str[0] = '\0';
   pFocusbar->focus = FALSE;

  /*
   * Connect to the expose signal.
   */
   gtk_signal_connect( GTK_OBJECT(pFocusbar->pWidget),
                       "expose-event",
                       (GtkSignalFunc) HandlerFocusbarExpose,
                       pFocusbar );			/* ID for expose handler */

  /*
   * Change the style.
   */
   gdk_color_alloc( gdk_colormap_get_system(), (GdkColor*)&color );
   pStyle = gtk_style_copy( pStyle );
   pStyle->bg[GTK_STATE_ACTIVE] = color;
   gtk_widget_set_style( pFocusbar->pWidget, pStyle );

   return pFocusbar;
}

/*****************************************************************************
 * Destroy a focus bar.
 *****************************************************************************/
void
FocusbarDestroy( focusbar_t* pFocusbar )
{
   if ( ! pFocusbar ) return;

   gtk_widget_destroy( pFocusbar->pWidget );
   g_free( pFocusbar );

   return;
}

/*****************************************************************************
 * Label the focus bar.
 *****************************************************************************/
void
FocusbarLabelSet( focusbar_t* pFocusbar,
                  char*       pStr )
{
g_return_if_fail( pFocusbar );

  /*
   * Record this label string.
   */
   strcpy( pFocusbar->str, pStr );

  /*
   * Repaint the focusbar.
   */
   FocusbarPaint( pFocusbar );

   return;
}

/*****************************************************************************
 * Tell focusbar it has gained the focus.
 *****************************************************************************/
void
FocusbarFocusGain( focusbar_t* pFocusbar )
{
g_return_if_fail( pFocusbar );

  /*
   * Record that the focus was gained.
   */
   pFocusbar->focus = TRUE;

  /*
   * Paint the focusbar appropriately.
   */
   FocusbarPaint( pFocusbar );

   return;
}

/*****************************************************************************
 * Tell focusbar it has lost the focus.
 *****************************************************************************/
void
FocusbarFocusLose( focusbar_t* pFocusbar )
{
g_return_if_fail( pFocusbar );

  /*
   * Record that the focus was lost.
   */
   pFocusbar->focus = FALSE;

  /*
   * Paint the focusbar appropriately.
   */
   FocusbarPaint( pFocusbar );

   return;
}

/*****************************************************************************
 * Paint a focusbar.  This function can be used for an expose event.
 *****************************************************************************/
void
FocusbarPaint( focusbar_t* pFocusbar )
{
g_return_if_fail( pFocusbar );

   if ( pFocusbar->focus )
      FocusbarPaintFocusGain( pFocusbar );
   else
      FocusbarPaintFocusLose( pFocusbar );

   return;
}

/*****************************************************************************
 * (internal) Paint the focusbar to indicate it has gained the focus.
 *****************************************************************************/
static void
FocusbarPaintFocusGain( focusbar_t* pFocusbar )
{
  /*
   * Draw black outline of rectangle.
   */
   gdk_draw_rectangle( pFocusbar->pWidget->window,
                       pFocusbar->pWidget->style->black_gc,
                       FALSE,	/* don't fill */
                       0, 0,	/* x,y */
                       pFocusbar->pWidget->allocation.width  -2,
                       pFocusbar->pWidget->allocation.height -2 );

  /*
   * Draw a filled rectange in a color that indicates focus.
   */
   gdk_draw_rectangle( pFocusbar->pWidget->window,
                       pFocusbar->pWidget->style->bg_gc[GTK_STATE_ACTIVE],
                       TRUE,	/* do fill */
                       1, 1,	/* x,y */
                       pFocusbar->pWidget->allocation.width  -3,
                       pFocusbar->pWidget->allocation.height -3 );

  /*
   * Draw the label.
   */
   FocusbarLabelDraw( pFocusbar );

   return;
}

/*****************************************************************************
 * (internal) Paint the focus bar to indicate it has lost the focus.
 *****************************************************************************/
static void
FocusbarPaintFocusLose( focusbar_t* pFocusbar )
{
  /*
   * Draw a filled rectange in a gray color (to indicate no-focus).
   */
   gdk_draw_rectangle( pFocusbar->pWidget->window,
                       pFocusbar->pWidget->style->bg_gc[GTK_STATE_NORMAL],
                       TRUE,	/* do fill */
                       0, 0,	/* x,y */
                       pFocusbar->pWidget->allocation.width,
                       pFocusbar->pWidget->allocation.height );

  /*
   * Draw the label.
   */
   FocusbarLabelDraw( pFocusbar );

   return;
}

/*****************************************************************************
 * (internal) Draw the text label in the focusbar.
 *****************************************************************************/
static void
FocusbarLabelDraw( focusbar_t* pFocusbar )
{
g_return_if_fail( pFocusbar );
   GdkFont * font=NULL;
   GtkStyle * style = gtk_widget_get_style( pFocusbar->pWidget);
   font = gdk_font_from_description(style->font_desc);

   gdk_draw_text( pFocusbar->pWidget->window,
                  font,//pFocusbar->pWidget->style->font,
                  pFocusbar->pWidget->style->black_gc,
                  FOCUSBAR_TEXT_OFFSET_FROM_LEFT,
                  pFocusbar->fontHeight - FOCUSBAR_TEXT_PADDING_BOTTOM,
                  pFocusbar->str,
                  strlen( pFocusbar->str ) );
  //lv
	return;
}

/*****************************************************************************
 * Handler for an expose event in a focusbar.
 *****************************************************************************/
gboolean
HandlerFocusbarExpose( GtkWidget*      pWidget,
                       GdkEventExpose* pEvent,
                       gpointer        pFocusbar )
{
   FocusbarPaint( (focusbar_t*)pFocusbar );

   return TRUE;
}
